<?php

namespace Xin\LaravelFortify\Model;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

/**
 * @mixin Model
 * @method Builder|$this simple(array|callable $appends = [])
 */
trait SimpleQuery
{

	/**
	 * 获取基础查询对象
	 *
	 * @param mixed $where
	 * @param array $options
	 * @return Builder|static
	 */
	public static function simpleQuery($where = null, $options = [])
	{
		$fields = static::simpleFields();

		if (isset($options['field'])) {
			if (is_callable($options['field'])) {
				$fields = $options['field']($fields);
			} else {
				$fields = $options['field'];
			}
			unset($options['field']);
		}

		/** @var Model $model */
		$model = new static;
		$newQuery = $model->select($fields);

		if ($where) {
			$newQuery->where($where);
		}

		return static::applyOptions($newQuery, $options);
	}

	/**
	 * 应用 options
	 *
	 * @param mixed $baseQuery
	 * @param array $options
	 * @return Builder|static
	 */
	public static function applyOptions($baseQuery, $options = null)
	{
		if ($options === null) {
			return $baseQuery;
		}

		if (is_callable($options)) {
			return $options($baseQuery);
		}

		foreach ($options as $method => $option) {
			if (method_exists($baseQuery, $method)) {
				if (is_array($option) && in_array($method, ['limit', 'page'])) {
					$baseQuery->$method(...$option);
				} else {
					$baseQuery->$method($option);
				}
			}
		}

		return $baseQuery;
	}

	/**
	 * 简单数据查询作用域
	 * @param Builder $query
	 * @param array|callable $appends
	 */
	public function scopeSimple(Builder $query, $appends = [])
	{
		$fields = static::simpleFields();

		if (is_callable($appends)) {
			$fields = $appends($fields, $query, $this);
		} else {
			$fields = array_merge($fields, $appends);
		}

		$query->select($fields);
	}

	/**
	 * @return array|string[]
	 */
	protected static function simpleFields()
	{
		$simpleFields = static::getSimpleFields();

		return empty($simpleFields) ? ['*'] : $simpleFields;
	}

	/**
	 * 获取列表要查询的字段列表，一般用于接口列表查询
	 *
	 * @return array|null
	 */
	public static function getSimpleFields()
	{
		return ['*'];
	}
}
